using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using GPSCore.NMEA.Interfaces;

namespace GPSCore.NMEA.FileSource
{
    /// <summary>
    /// This is a NMEA Sentence source 
    /// </summary>
    public class NMEAFileReader : IDisposable , INMEASource
    {
        #region members

        //the file path name    full path    and the file is a normal ASCII text file
        private string m_filePath;

        private System.IO.StreamReader m_fileReader;

        private bool m_doRead;
        private ThreadStart m_readThreadStart;
        private Thread m_readThread;

        #endregion

        #region constructors

        /// <summary>
        /// Void constructors
        /// </summary>
        public NMEAFileReader()
        {
            m_doRead = false;
        }

        /// <summary>
        /// Create a FileReader IGPSSource
        /// </summary>
        /// <param name="filePath"></param>
        public NMEAFileReader(string filePath)
        {
            m_doRead = false;
            m_filePath = filePath;
        }

        #endregion
        
        #region thread

        /// <summary>
        /// Initialize the Thread
        /// </summary>
        private void initThread()
        {
            m_readThreadStart = new ThreadStart(readingThread);
            m_readThread = new Thread(m_readThreadStart);
        }

        /// <summary>
        /// internal reading thread
        /// </summary>
        private void readingThread()
        {
            string message;

            try
            {
                while (m_doRead & !m_fileReader.EndOfStream)
                {
                        lock (this)
                        {
                            message = m_fileReader.ReadLine();
                        }

                        //FIRE EXTERNALLY AN EVENT!
                        if (OnNMEASentenceRecieved != null)
                        {
                            NMEASentenceRecieved extEvent = new NMEASentenceRecieved(OnNMEASentenceRecieved);
                            extEvent.Invoke(message);
                        }
                }

                if (m_fileReader.EndOfStream)
                { 
                    //FIRE EXTERNALLY AN EVENT!
                    if (OnNMEAForceStop != null)
                    {
                        NMEAForceStop extEvent = new NMEAForceStop(OnNMEAForceStop);
                        extEvent.Invoke();
                    }
                }
            }
            catch (Exception ex)
            {
                string exMess = ex.Message;
            }

            this.Stop();
        }

        #endregion

        #region properties

        /// <summary>
        /// File Path
        /// </summary>
        public string FilePath
        {
            get { return m_filePath; }
            set { m_filePath = value; }
        }

        #endregion

        #region IGPSSource Members


        /// <summary>
        /// A new NNEA Sentence is readed
        /// </summary>
        public event NMEASentenceRecieved OnNMEASentenceRecieved;

        /// <summary>
        /// End of file reach!?
        /// </summary>
        public event NMEAForceStop OnNMEAForceStop;

        /// <summary>
        /// Start to read NMEA Sentence
        /// </summary>
        /// <returns></returns>
        public bool Start()
        {
            if (m_filePath != null)
            {
                try
                {
                    m_fileReader = new System.IO.StreamReader(m_filePath);
                }
                catch (Exception ex)
                {
                    string exMess = ex.Message;
                }

                m_doRead = true;

                initThread();

                //start the reading thred
                m_readThread.IsBackground = true;
                m_readThread.Start();

                return true;
            }

            return false;
        }

        /// <summary>
        /// Stop to read NMEA Sentece
        /// </summary>
        /// <returns></returns>
        public bool Stop()
        {
            try
            {
                if (m_fileReader != null)
                {
                    m_doRead = false;

                    m_fileReader.Dispose();
                    m_fileReader = null;
                }

                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        #endregion

        #region IDisposable Members

        void IDisposable.Dispose()
        {
            if (m_fileReader != null)
            {
                if (m_doRead)
                {
                    m_doRead = false;
                }

                lock (this)
                {
                    if (m_fileReader != null)
                    {
                        m_fileReader.Dispose();
                        m_fileReader = null;
                    }
                }
            }
        }

        #endregion
    }
}
